package system

import (
	"bytes"
	"errors"
	"fmt"
	"time"

	"counter-help/admin/server/global"
	"counter-help/admin/server/model/common/request"
	"counter-help/admin/server/model/system"

	"github.com/xuri/excelize/v2"
	"go.uber.org/zap"
)

type UUIDLicenseService struct{}

// ValidateUUID 验证UUID并更新访问次数，返回状态码、过期剩余天数和错误信息
func (s *UUIDLicenseService) ValidateUUID(uuid string) (int, int, error) {
	var license system.UUIDLicense
	if err := global.GVA_DB.Where("uuid = ?", uuid).First(&license).Error; err != nil {
		return 7, 0, errors.New("UUID不存在")
	}

	// 检查是否激活
	if !license.IsActive {
		return 8, 0, errors.New("UUID未激活")
	}

	// 计算剩余天数
	remainingDays := 0
	now := time.Now()
	if license.ExpireTime.After(now) {
		remainingDays = int(license.ExpireTime.Sub(now).Hours()/24) + 1
	}

	// 检查是否过期
	if now.After(license.ExpireTime) {
		return 9, 0, errors.New("UUID已过期")
	}

	// 检查总访问次数是否超限
	if license.TotalAccess >= license.TotalAccessLimit {
		return 11, remainingDays, errors.New("UUID总访问次数已达上限")
	}

	// 检查每日访问次数
	if now.Format("2006-01-02") != license.LastAccessDate.Format("2006-01-02") {
		// 如果是新的一天，重置当日访问次数
		license.CurrentDayAccess = 0
		license.LastAccessDate = now

		// 记录日期重置事件
		global.GVA_LOG.Info("检测到新的一天，重置当日访问次数",
			zap.String("uuid", uuid),
			zap.String("lastAccessDate", license.LastAccessDate.Format("2006-01-02")),
			zap.String("currentDate", now.Format("2006-01-02")))
	}

	if license.CurrentDayAccess >= license.DailyAccessLimit {
		return 10, remainingDays, errors.New("UUID当日访问次数已达上限")
	}

	// 更新访问次数
	license.CurrentDayAccess++
	license.TotalAccess++
	license.LastAccessDate = now

	if err := global.GVA_DB.Save(&license).Error; err != nil {
		return 12, remainingDays, errors.New("更新访问记录失败")
	}

	return 0, remainingDays, nil
}

// 验证UUID格式
func validateUUIDFormat(uuid string) bool {
	return len(uuid) == 36
}

// CreateUUIDLicense 创建UUID许可证
func (s *UUIDLicenseService) CreateUUIDLicense(license *system.UUIDLicense) error {
	// 验证UUID格式
	if !validateUUIDFormat(license.UUID) {
		return errors.New("UUID格式不正确")
	}

	// 检查UUID是否已存在
	var count int64
	if err := global.GVA_DB.Model(&system.UUIDLicense{}).Where("uuid = ?", license.UUID).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("UUID已存在")
	}

	return global.GVA_DB.Create(license).Error
}

// UpdateUUIDLicense 更新UUID许可证
func (s *UUIDLicenseService) UpdateUUIDLicense(license *system.UUIDLicense) error {
	updates := map[string]interface{}{
		"expire_time":        license.ExpireTime,
		"is_active":          license.IsActive,
		"description":        license.Description,
		"daily_access_limit": license.DailyAccessLimit,
		"total_access_limit": license.TotalAccessLimit,
	}

	if err := global.GVA_DB.Model(&system.UUIDLicense{}).Where("uuid = ?", license.UUID).Updates(updates).Error; err != nil {
		return errors.New("更新失败")
	}

	return nil
}

// DeleteUUIDLicense 删除UUID许可证
func (s *UUIDLicenseService) DeleteUUIDLicense(uuid string) error {
	if uuid == "" {
		return errors.New("UUID不能为空")
	}

	// 先检查UUID是否存在
	var license system.UUIDLicense
	if err := global.GVA_DB.Where("uuid = ?", uuid).First(&license).Error; err != nil {
		return errors.New("UUID不存在")
	}

	// 执行真删除操作
	if err := global.GVA_DB.Unscoped().Delete(&license).Error; err != nil {
		return errors.New("删除失败")
	}

	return nil
}

// GetUUIDList 获取UUID许可证列表
func (s *UUIDLicenseService) GetUUIDList(info request.PageInfo) (list []system.UUIDLicense, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)

	db := global.GVA_DB.Model(&system.UUIDLicense{})

	// 如果有搜索关键词，添加搜索条件
	if info.Keyword != "" {
		searchKey := "%" + info.Keyword + "%"
		db = db.Where("uuid LIKE ?", searchKey)
	}

	// 获取总数
	err = db.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}

	// 处理排序
	orderStr := "created_at desc" // 默认排序
	if info.Sort != "" && info.Order != "" {
		// 验证排序字段，防止SQL注入
		validSortFields := map[string]bool{
			"daily_access_limit": true,
			"current_day_access": true,
			"total_access_limit": true,
			"total_access":       true,
			"created_at":         true,
			"expire_time":        true,
		}

		if validSortFields[info.Sort] {
			orderDirection := "asc"
			if info.Order == "desc" {
				orderDirection = "desc"
			}
			orderStr = info.Sort + " " + orderDirection

			// 特别处理过期时间排序，添加UUID作为二级排序确保结果稳定
			if info.Sort == "expire_time" {
				orderStr = orderStr + ", uuid asc"
			}
		}
	}

	// 获取列表
	err = db.Limit(limit).Offset(offset).Order(orderStr).Find(&list).Error
	if err != nil {
		return nil, 0, err
	}

	return list, total, nil
}

// RenewUUID 续费UUID许可证
func (s *UUIDLicenseService) RenewUUID(uuid string, renewType string, renewValue int) error {
	if uuid == "" {
		return errors.New("UUID不能为空")
	}

	// 先检查UUID是否存在
	var license system.UUIDLicense
	if err := global.GVA_DB.Where("uuid = ?", uuid).First(&license).Error; err != nil {
		global.GVA_LOG.Error("续费失败: UUID不存在", zap.String("uuid", uuid), zap.Error(err))
		return errors.New("UUID不存在")
	}

	// 记录查询到的许可证信息
	global.GVA_LOG.Info("查询到的许可证信息",
		zap.String("uuid", license.UUID),
		zap.Time("expireTime", license.ExpireTime),
		zap.Bool("isActive", license.IsActive),
	)

	// 保存旧的过期时间
	oldExpireTime := license.ExpireTime

	// 确定续费的基准时间
	// 如果已经过期，则从当前时间开始计算
	// 如果未过期，则在原过期时间基础上叠加
	now := time.Now()
	var baseTime time.Time
	if now.After(oldExpireTime) {
		// 已过期，从当前时间开始
		baseTime = now
	} else {
		// 未过期，在原有基础上叠加
		baseTime = oldExpireTime
	}

	// 计算新的过期时间
	var newExpireTime time.Time
	switch renewType {
	case "day":
		newExpireTime = baseTime.AddDate(0, 0, renewValue)
	case "month":
		newExpireTime = baseTime.AddDate(0, renewValue, 0)
	default:
		global.GVA_LOG.Error("续费失败: 续费类型无效", zap.String("renewType", renewType))
		return errors.New("续费类型无效")
	}

	global.GVA_LOG.Info("续费信息",
		zap.String("uuid", uuid),
		zap.String("renewType", renewType),
		zap.Int("renewValue", renewValue),
		zap.Time("oldExpireTime", oldExpireTime),
		zap.Time("newExpireTime", newExpireTime),
	)

	// 更新过期时间
	if err := global.GVA_DB.Model(&system.UUIDLicense{}).
		Where("uuid = ?", uuid).
		Update("expire_time", newExpireTime).
		Error; err != nil {
		global.GVA_LOG.Error("更新过期时间失败", zap.Error(err))
		return errors.New("更新过期时间失败: " + err.Error())
	}

	// 创建续费记录
	renewalRecord := system.UUIDRenewalRecord{
		UUID:           uuid,
		RenewalType:    renewType,
		RenewalValue:   renewValue,
		OldExpireTime:  oldExpireTime,
		NewExpireTime:  newExpireTime,
		OperatorUserID: 0,
		Remark:         "通过系统续费",
	}

	global.GVA_LOG.Info("准备创建续费记录", zap.Any("renewalRecord", renewalRecord))

	if err := global.GVA_DB.Create(&renewalRecord).Error; err != nil {
		global.GVA_LOG.Error("创建续费记录失败", zap.Error(err))
		return errors.New("创建续费记录失败: " + err.Error())
	}

	global.GVA_LOG.Info("续费成功完成", zap.String("uuid", uuid))
	return nil
}

// GetUUIDRenewalRecords 获取UUID的续费记录
func (s *UUIDLicenseService) GetUUIDRenewalRecords(uuid string) ([]system.UUIDRenewalRecord, error) {
	var records []system.UUIDRenewalRecord

	if err := global.GVA_DB.Where("uuid = ?", uuid).Order("created_at desc").Find(&records).Error; err != nil {
		return nil, err
	}

	return records, nil
}

// GetUUIDExportData 获取带有续费信息的UUID导出数据
func (s *UUIDLicenseService) GetUUIDExportData(info request.PageInfo) (list []system.UUIDExportData, total int64, err error) {
	// 先获取UUID列表
	licenses, total, err := s.GetUUIDList(info)
	if err != nil {
		return nil, 0, err
	}

	// 初始化导出数据列表
	exportDataList := make([]system.UUIDExportData, 0, len(licenses))

	// 为每个UUID添加续费信息
	for _, license := range licenses {
		// 获取该UUID的续费记录
		records, err := s.GetUUIDRenewalRecords(license.UUID)
		if err != nil {
			global.GVA_LOG.Error("获取UUID续费记录失败", zap.Error(err), zap.String("uuid", license.UUID))
			continue
		}

		// 计算总续费天数
		totalRenewalDays := 0
		for _, record := range records {
			if record.RenewalType == "day" {
				totalRenewalDays += record.RenewalValue
			} else { // 按月续费
				totalRenewalDays += record.RenewalValue * 30 // 按每月30天计算
			}
		}

		// 创建导出数据
		exportData := system.UUIDExportData{
			UUIDLicense:      license,
			RenewalCount:     len(records),
			TotalRenewalDays: totalRenewalDays,
		}

		// 设置最近续费时间
		if len(records) > 0 {
			exportData.LastRenewalTime = records[0].CreatedAt
		}

		exportDataList = append(exportDataList, exportData)
	}

	return exportDataList, total, nil
}

// ResetDailyAccess 重置所有UUID的当日访问次数
func (s *UUIDLicenseService) ResetDailyAccess() error {
	now := time.Now()
	today := now.Format("2006-01-02")

	// 只重置那些 last_access_date 不是今天的记录
	// 这样可以避免重置已经是今天访问过的UUID
	result := global.GVA_DB.Model(&system.UUIDLicense{}).
		Where("DATE(last_access_date) != ?", today).
		Update("current_day_access", 0)

	if result.Error != nil {
		global.GVA_LOG.Error("重置当日访问次数失败", zap.Error(result.Error))
		return result.Error
	}

	global.GVA_LOG.Info("成功重置UUID的当日访问次数",
		zap.String("today", today),
		zap.Int64("affected_rows", result.RowsAffected))
	return nil
}

// GenerateExcel 生成Excel文件
func (s *UUIDLicenseService) GenerateExcel(list []system.UUIDLicense) ([]byte, error) {
	// 创建新的Excel文件
	f := excelize.NewFile()

	// 创建Sheet
	sheetName := "UUID列表"
	index, err := f.NewSheet(sheetName)
	if err != nil {
		global.GVA_LOG.Error("创建Sheet失败", zap.Error(err))
		return nil, err
	}

	// 设置默认Sheet
	f.SetActiveSheet(index)

	// 设置列标题
	titles := []string{"UUID", "创建时间", "过期时间", "剩余时间", "是否激活", "每日访问限制", "当日访问次数", "总访问限制", "总访问次数", "描述"}
	for i, title := range titles {
		cell := fmt.Sprintf("%c%d", 'A'+i, 1)
		f.SetCellValue(sheetName, cell, title)
	}

	// 设置标题行样式
	titleStyle, err := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold: true,
			Size: 12,
		},
		Fill: excelize.Fill{
			Type:    "pattern",
			Color:   []string{"#E0E0E0"},
			Pattern: 1,
		},
		Alignment: &excelize.Alignment{
			Horizontal: "center",
			Vertical:   "center",
		},
		Border: []excelize.Border{
			{Type: "left", Color: "#000000", Style: 1},
			{Type: "top", Color: "#000000", Style: 1},
			{Type: "right", Color: "#000000", Style: 1},
			{Type: "bottom", Color: "#000000", Style: 1},
		},
	})
	if err != nil {
		global.GVA_LOG.Error("设置标题样式失败", zap.Error(err))
	} else {
		titleRange := fmt.Sprintf("A1:J1")
		f.SetCellStyle(sheetName, titleRange, titleRange, titleStyle)
	}

	// 填充数据
	for i, item := range list {
		row := i + 2 // 从第2行开始

		// 计算剩余时间
		var remainingTime string
		now := time.Now()
		if now.After(item.ExpireTime) {
			remainingTime = "已过期"
		} else {
			diffTime := item.ExpireTime.Sub(now)
			days := int(diffTime.Hours()) / 24
			months := days / 30
			remainingDays := days % 30

			if months > 0 {
				remainingTime = fmt.Sprintf("%d个月%d天", months, remainingDays)
			} else {
				remainingTime = fmt.Sprintf("%d天", remainingDays)
			}
		}

		// 设置单元格值
		f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), item.UUID)
		f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), item.CreatedAt.Format("2006-01-02 15:04:05"))
		f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), item.ExpireTime.Format("2006-01-02 15:04:05"))
		f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), remainingTime)

		// 将布尔值转换为文本显示
		statusText := "否"
		if item.IsActive {
			statusText = "是"
		}
		f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), statusText)

		f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), item.DailyAccessLimit)
		f.SetCellValue(sheetName, fmt.Sprintf("G%d", row), item.CurrentDayAccess)
		f.SetCellValue(sheetName, fmt.Sprintf("H%d", row), item.TotalAccessLimit)
		f.SetCellValue(sheetName, fmt.Sprintf("I%d", row), item.TotalAccess)
		f.SetCellValue(sheetName, fmt.Sprintf("J%d", row), item.Description)
	}

	// 调整列宽
	columnWidths := map[string]float64{
		"A": 40, // UUID
		"B": 20, // 创建时间
		"C": 20, // 过期时间
		"D": 15, // 剩余时间
		"E": 10, // 状态
		"F": 15, // 每日访问限制
		"G": 15, // 当日访问次数
		"H": 15, // 总访问限制
		"I": 15, // 总访问次数
		"J": 40, // 描述
	}

	for col, width := range columnWidths {
		f.SetColWidth(sheetName, col, col, width)
	}

	// 将文件写入buffer
	var buffer bytes.Buffer
	if err := f.Write(&buffer); err != nil {
		global.GVA_LOG.Error("写入Excel失败", zap.Error(err))
		return nil, err
	}

	return buffer.Bytes(), nil
}
